package edu.ustb.mis.dm.simpleTest;

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.poi.ss.usermodel.Workbook;
import edu.ustb.mis.dm.Constants;
import edu.ustb.mis.dm.impl.algorithm.TextInputAndTextOutputCABOSFV;
import edu.ustb.mis.dm.interfaces.algorithm.ClusterAlgorithm;
import edu.ustb.mis.dm.model.AccuracyModel;
import edu.ustb.mis.dm.model.ClusterResult;
import edu.ustb.mis.dm.model.ValueModel;
import edu.ustb.mis.dm.model.unit.impl.Instance;
import edu.ustb.mis.dm.util.EntryComparator;
import edu.ustb.mis.excel.utils.ExcelExporter;

public class CABOSFV_2 {
	private List<Instance> instanceList = new ArrayList<Instance>();

	private static List<AccuracyModel> accuracyList;

	private static final DecimalFormat THRESHHOLD_FORMAT = new DecimalFormat("#.##");

	/**
	 * @param args
	 */
	public static void main(final String[] args) {
		for (float j = 1.03f; j < 1.31f; j += 0.01) {
			accuracyList = new ArrayList<AccuracyModel>();
			System.out.println(j);
			final CABOSFV_2 c2 = new CABOSFV_2();
			for (int i = 0; i < 10000; i++) {
				System.out.println(i);
				c2.exec(j);
			}
			try {
				c2.export(accuracyList, j);
			} catch (final Exception e) {
				e.printStackTrace();
			}
			//System.out.println("over");
		}
		ResultAy ra = new ResultAy();
		ra.imp();
//		RunLinuxCommand rlc = new RunLinuxCommand();
//		rlc.run();
	}

	private List<ClusterResult> resultList = new ArrayList<ClusterResult>();

	public void accuracy(final List<ClusterResult> resultList) {
		final Map<String, Integer> standMap = new HashMap<String, Integer>();
		init(standMap);
		final List<Map<String, ValueModel>> resultMapList = new ArrayList<Map<String, ValueModel>>();
		Collections.sort(resultList);
		int correct = 0, all = 0;
		Map<String, ValueModel> resultMap;
		for (final ClusterResult cr : resultList) {
			all += cr.getClassIDList().size();
			resultMap = new HashMap<String, ValueModel>();
			for (String classId : cr.getClassIDList()) {
				//classId = classId.substring(0, 3);
				//classId = classId.substring(classId.length() - 1);
				if (resultMap.containsKey(classId)) {
					resultMap.get(classId).increase();
				} else {
					resultMap.put(classId, new ValueModel(1));
				}
			}
			resultMapList.add(resultMap);
		}
		final Set<Entry<String, Integer>> entrySet = standMap.entrySet();
		final List<Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(entrySet);
		Collections.sort(entryList, new EntryComparator());
		String classId;
		for (final Entry<String, Integer> entry : entryList) {
			classId = entry.getKey();
			final List<ValueModel> modelList = new ArrayList<ValueModel>();
			for (final Map<String, ValueModel> map : resultMapList) {
				if (map.containsKey(classId) && !Boolean.FALSE.equals(map.get(classId).getStatus())) {
					modelList.add(map.get(classId));
				}
			}
			Collections.sort(modelList);
			if (modelList.size() != 0) {
				correct += modelList.get(0).getValue();
				final int code = modelList.get(0).hashCode();
				for (final Map<String, ValueModel> map : resultMapList) {
					if (map.containsKey(classId)) {
						if (map.get(classId).hashCode() == code) {
							for (final Entry<String, ValueModel> e : map.entrySet()) {
								if (e.getKey().equals(classId)) {
									e.getValue().setStatus(Boolean.TRUE);
								} else {
									e.getValue().setStatus(Boolean.FALSE);
								}
							}
						} else {
							map.get(classId).setStatus(Boolean.FALSE);
						}
					}
				}
			}
		}
		//System.out.println(correct + "/" + all);
		accuracyList.add(new AccuracyModel(correct, all, resultList.size()));
	}

	public void exec(float j) {
		ClusterAlgorithm<ClusterResult> cabosfv;
		cabosfv = new TextInputAndTextOutputCABOSFV(Constants.MUSHROOM__FILL_NAME);
		cabosfv.setThreshhold(j);
		//cabosfv.setThreshhold(0.0444444);
		//cabosfv.setThreshhold(0.145);
		cabosfv.execute();
		instanceList = ((TextInputAndTextOutputCABOSFV)cabosfv).getInstanceList();
		resultList = cabosfv.getResultList();
		//cabosfv = new STextOutputCABOSFV(resultList);
		//cabosfv.setThreshhold(1);
		//cabosfv.setThreshhold(0.115);
		//cabosfv.execute();
		resultList = cabosfv.getResultList();
		//System.out.println(resultList.size());
		accuracy(resultList);
	}

	private void export(final Collection<AccuracyModel> excelModelList, float j) throws Exception {
		final OutputStream out = new FileOutputStream("output/eapx/process/accuracy" + THRESHHOLD_FORMAT.format(j) + ".xlsx");
		final ExcelExporter<AccuracyModel> ex = new ExcelExporter<AccuracyModel>();
		final Workbook wb = ex.exportExcel("正确率结果", excelModelList, "2007");
		wb.write(out);
		out.flush();
		out.close();
	}

	public void init(final Map<String, Integer> standMap) {
		String  id;
		for (final Instance instance : instanceList) {
			id = instance.getClassID();
			//id = id.substring(0, 3);
			//id = id.substring(id.length() - 1);
			if (standMap.containsKey(id)) {
				standMap.put(id, standMap.get(id) + 1);
			} else {
				standMap.put(id, 1);
			}
		}
	}
}
